/**
 * 路线规划工具类
 * 支持路径规划和导航
 */

import { Map as OlMap } from 'ol';
import { Vector as VectorLayer } from 'ol/layer';
import { Vector as VectorSource } from 'ol/source';
import { Feature } from 'ol';
import { LineString, Point } from 'ol/geom';
import { Style, Stroke, Circle, Fill, Icon, Text } from 'ol/style';
import { Coordinate } from '../types';
import { DataUtil } from '../utils/data';
import { EventEmitter } from '../utils/event';

/**
 * 路线点
 */
export interface RoutePoint {
  /** 坐标 */
  coordinate: Coordinate;
  /** 名称 */
  name?: string;
  /** 类型：起点、途经点、终点 */
  type?: 'start' | 'waypoint' | 'end';
}

/**
 * 路线结果
 */
export interface RouteResult {
  /** 路线坐标点数组 */
  coordinates: Coordinate[];
  /** 总距离（米） */
  distance: number;
  /** 预计时间（秒） */
  duration?: number;
  /** 路线步骤 */
  steps?: RouteStep[];
}

/**
 * 路线步骤
 */
export interface RouteStep {
  /** 步骤描述 */
  instruction: string;
  /** 距离（米） */
  distance: number;
  /** 时间（秒） */
  duration?: number;
  /** 坐标 */
  coordinate: Coordinate;
}

/**
 * 路线配置
 */
export interface RouteOptions {
  /** 路线服务提供商 */
  provider?: 'osrm' | 'gaode' | 'baidu' | 'custom';
  /** 自定义路线URL */
  routeUrl?: string;
  /** API Key */
  apiKey?: string;
  /** 路线样式 */
  routeStyle?: any;
  /** 起点样式 */
  startStyle?: any;
  /** 终点样式 */
  endStyle?: any;
  /** 途经点样式 */
  waypointStyle?: any;
}

/**
 * 路线规划工具类
 */
export class Route extends EventEmitter {
  /** 地图实例 */
  private map: OlMap | null = null;
  /** 路线图层 */
  private routeLayer: VectorLayer<VectorSource<Feature>> | null = null;
  /** 路线数据源 */
  private routeSource: VectorSource<Feature> | null = null;
  /** 配置选项 */
  private options: RouteOptions;
  /** 当前路线 */
  private currentRoute: RouteResult | null = null;

  /**
   * 构造函数
   * @param options 配置选项
   */
  constructor(options: RouteOptions = {}) {
    super();
    this.options = {
      provider: 'osrm',
      ...options
    };
    this.createLayer();
  }

  /**
   * 创建路线图层
   */
  private createLayer(): void {
    this.routeSource = new VectorSource<Feature>();
    this.routeLayer = new VectorLayer({
      source: this.routeSource,
      style: (feature) => this.getStyle(feature as Feature)
    });
  }

  /**
   * 获取样式
   */
  private getStyle(feature: Feature): Style | Style[] {
    const geometry = feature.getGeometry();
    const featureType = feature.get('type');

    if (geometry instanceof LineString) {
      // 路线样式
      return this.options.routeStyle || new Style({
        stroke: new Stroke({
          color: '#3399CC',
          width: 4
        })
      });
    } else if (geometry instanceof Point) {
      // 点样式
      if (featureType === 'start') {
        return this.options.startStyle || new Style({
          image: new Circle({
            radius: 8,
            fill: new Fill({ color: '#00FF00' }),
            stroke: new Stroke({ color: '#fff', width: 2 })
          })
        });
      } else if (featureType === 'end') {
        return this.options.endStyle || new Style({
          image: new Circle({
            radius: 8,
            fill: new Fill({ color: '#FF0000' }),
            stroke: new Stroke({ color: '#fff', width: 2 })
          })
        });
      } else {
        return this.options.waypointStyle || new Style({
          image: new Circle({
            radius: 6,
            fill: new Fill({ color: '#FFA500' }),
            stroke: new Stroke({ color: '#fff', width: 2 })
          })
        });
      }
    }

    return new Style();
  }

  /**
   * 初始化路线工具
   * @param map 地图实例
   */
  init(map: OlMap): void {
    if (this.map) {
      this.destroy();
    }

    this.map = map;
    
    // 添加图层
    if (this.routeLayer) {
      map.addLayer(this.routeLayer);
    }
  }

  /**
   * 规划路线
   * @param points 路线点数组
   * @returns Promise<RouteResult>
   */
  async plan(points: RoutePoint[]): Promise<RouteResult> {
    if (points.length < 2) {
      throw new Error('At least 2 points are required for routing');
    }

    const provider = this.options.provider || 'osrm';

    try {
      let result: RouteResult;

      if (provider === 'osrm') {
        result = await this.planOSRM(points);
      } else if (provider === 'gaode') {
        result = await this.planGaode(points);
      } else if (provider === 'baidu') {
        result = await this.planBaidu(points);
      } else if (provider === 'custom' && this.options.routeUrl) {
        result = await this.planCustom(points);
      } else {
        throw new Error(`Unsupported provider: ${provider}`);
      }

      this.currentRoute = result;
      this.drawRoute(points, result);
      this.emit('routeplan', result);

      return result;
    } catch (error) {
      this.emit('error', error);
      throw error;
    }
  }

  /**
   * 使用 OSRM 规划路线
   */
  private async planOSRM(points: RoutePoint[]): Promise<RouteResult> {
    // 构建坐标字符串
    const coordString = points.map(p => `${p.coordinate[0]},${p.coordinate[1]}`).join(';');
    const url = `https://router.project-osrm.org/route/v1/driving/${coordString}?overview=full&geometries=geojson`;

    const response = await fetch(url);
    const data = await response.json();

    if (data.code !== 'Ok') {
      throw new Error(`Routing failed: ${data.message || 'Unknown error'}`);
    }

    const route = data.routes[0];
    const coordinatesGeo = route.geometry.coordinates;
    const coordinates: Coordinate[] = coordinatesGeo.map((coord: number[]) => [coord[0], coord[1]]);

    return {
      coordinates,
      distance: route.distance,
      duration: route.duration,
      steps: route.legs?.flatMap((leg: any) => leg.steps || []) || []
    };
  }

  /**
   * 使用高德地图规划路线
   */
  private async planGaode(points: RoutePoint[]): Promise<RouteResult> {
    if (!this.options.apiKey) {
      throw new Error('Gaode API key is required');
    }

    const origin = `${points[0].coordinate[0]},${points[0].coordinate[1]}`;
    const destination = `${points[points.length - 1].coordinate[0]},${points[points.length - 1].coordinate[1]}`;
    const waypoints = points.slice(1, -1).map(p => `${p.coordinate[0]},${p.coordinate[1]}`).join('|');

    let url = `https://restapi.amap.com/v3/direction/driving?key=${this.options.apiKey}&origin=${origin}&destination=${destination}`;
    if (waypoints) {
      url += `&waypoints=${waypoints}`;
    }

    const response = await fetch(url);
    const data = await response.json();

    if (data.status !== '1') {
      throw new Error(`Routing failed: ${data.info}`);
    }

    const path = data.route.paths[0];
    const coordinates: Coordinate[] = path.steps.flatMap((step: any) => 
      step.polyline.split(';').map((point: string) => {
        const [lng, lat] = point.split(',').map(parseFloat);
        return [lng, lat] as Coordinate;
      })
    );

    return {
      coordinates,
      distance: path.distance,
      duration: path.duration,
      steps: path.steps.map((step: any, index: number) => {
        const stepCoords = step.polyline.split(';').map((point: string) => {
          const [lng, lat] = point.split(',').map(parseFloat);
          return [lng, lat] as Coordinate;
        });
        return {
          instruction: step.instruction,
          distance: step.distance,
          duration: step.duration,
          coordinate: stepCoords[0] || coordinates[0]
        };
      })
    };
  }

  /**
   * 使用百度地图规划路线
   */
  private async planBaidu(points: RoutePoint[]): Promise<RouteResult> {
    if (!this.options.apiKey) {
      throw new Error('Baidu API key is required');
    }

    // 百度地图路线规划实现
    // 注意：需要处理坐标转换（WGS84 -> BD09）
    throw new Error('Baidu routing not implemented yet');
  }

  /**
   * 自定义路线规划
   */
  private async planCustom(points: RoutePoint[]): Promise<RouteResult> {
    if (!this.options.routeUrl) {
      throw new Error('Custom route URL is required');
    }

    // 自定义路线规划实现
    throw new Error('Custom routing not implemented yet');
  }

  /**
   * 绘制路线
   */
  private drawRoute(points: RoutePoint[], result: RouteResult): void {
    if (!this.routeSource) return;

    this.routeSource.clear();

    // 绘制路线
    const lineFeature = new Feature({
      geometry: new LineString(result.coordinates.map(coord => DataUtil.toOlCoordinate(coord)))
    });
    lineFeature.set('type', 'route');
    this.routeSource.addFeature(lineFeature);

    // 绘制起点、途经点、终点
    points.forEach((point, index) => {
      const type = index === 0 ? 'start' : (index === points.length - 1 ? 'end' : 'waypoint');
      const pointFeature = new Feature({
        geometry: new Point(DataUtil.toOlCoordinate(point.coordinate))
      });
      pointFeature.set('type', type);
      // 确保routeSource不为null
      this.routeSource!.addFeature(pointFeature);
    });
  }

  /**
   * 清除路线
   */
  clear(): void {
    if (this.routeSource) {
      this.routeSource.clear();
    }
    this.currentRoute = null;
    this.emit('clear');
  }

  /**
   * 获取当前路线
   */
  getCurrentRoute(): RouteResult | null {
    return this.currentRoute;
  }

  /**
   * 销毁路线工具
   */
  destroy(): void {
    this.clear();
    
    if (this.map && this.routeLayer) {
      this.map.removeLayer(this.routeLayer);
    }

    this.map = null;
    this.removeAllListeners();
    this.emit('destroy');
  }
}

